use crate::modeling::{Class, ClassAttribute, Value};

use std::collections::HashMap;

pub trait ValueMapper {
    fn to_value(&self, class: &Class, value: &Value) -> anyhow::Result<Value> {
        match value {
            Value::Object(m) => {
                return self.map_to_value(class, m);
            }
            _ => Ok(value.clone()),
        }
    }
    fn map_to_value(&self, class: &Class, value: &HashMap<String, Value>) -> anyhow::Result<Value> {
        //循环属性
        if let Some(attributes) = &class.attributes {
            //
            let mut values = HashMap::new();

            for attribute in attributes {
                //
                if let Ok(temp) = _get_like_value(attribute, value) {
                    if let Ok(new_value) = temp.convert(&attribute.data_type) {
                        values.insert(attribute.name.clone(), new_value);
                        continue;
                    } else {
                        tracing::error!(
                            "数据类型尝试转换失败:{:?}->{:?}",
                            temp,
                            &attribute.data_type
                        );
                    }
                }
                //
            }
            Ok(Value::Object(values))
        } else {
            Ok(Value::Object(value.clone()))
        }
    }
}

fn _get_like_value<'a>(
    attribute: &ClassAttribute,
    value: &'a HashMap<String, Value>,
) -> anyhow::Result<&'a Value> {
    //通过名称获取值
    let name = &attribute.name;
    if let Some(v) = value.get(name) {
        return Ok(v);
    }
    Err(anyhow::anyhow!(""))
}
